package com.keyue.common.utils;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.internal.OSSHeaders;
import com.aliyun.oss.model.*;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.auth.sts.AssumeRoleRequest;
import com.aliyuncs.auth.sts.AssumeRoleResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.http.ProtocolType;
import com.aliyuncs.profile.DefaultProfile;
import com.keyue.config.AliOssConfig;
import lombok.extern.slf4j.Slf4j;

import java.io.ByteArrayInputStream;
import java.net.URL;
import java.util.*;

/**
 * @author: xms
 * @description: 阿里oss图片存储工具类
 * @date: 2023/10/30 18:24
 * @version: 1.0
 */
@Slf4j
public class AliOssUtil {

    /**
     * oss 客户端
     */
    private static OSS client;

    private static IAcsClient acsClient;

    public Map<String, Object> aliyunCertificate() {
        AssumeRoleRequest request = new AssumeRoleRequest();
        request.setRoleArn(AliOssConfig.ALIYUN_ROLEARN);
        request.setRoleSessionName(UUID.randomUUID().toString());
        AssumeRoleResponse response = null;
        try {
            response = acsClient.getAcsResponse(request);
        } catch (ClientException e) {
            throw new RuntimeException(e);
        }
        Map<String, Object> map = new HashMap<>();
        map.put("securityToken", response.getCredentials().getSecurityToken());
        map.put("expiration", response.getCredentials().getExpiration());
        map.put("accessKeySecret", response.getCredentials().getAccessKeySecret());
        map.put("accessKeyId", response.getCredentials().getAccessKeyId());
        map.put("regionid", AliOssConfig.ALIYUN_ENDPOINT);
        return map;
    }


    static {
        client = new OSSClientBuilder().build(AliOssConfig.ALIYUN_ENDPOINT, AliOssConfig.ALIYUN_ACCESS_ID, AliOssConfig.ALIYUN_ACCESS_KEY);
        DefaultProfile profile = DefaultProfile.getProfile(AliOssConfig.ALIYUN_ENDPOINT, AliOssConfig.ALIYUN_ACCESS_ID, AliOssConfig.ALIYUN_ACCESS_KEY);
        acsClient = new DefaultAcsClient(profile);
    }

    /**
     * 实现文件名的重命名和限长
     *
     * @param fileName
     * @return
     */
    public static String getUniqueFileName(String fileName) {
        if (fileName.length() > 50) {
            fileName = fileName.substring(fileName.length() - 50);
        }
        return System.currentTimeMillis() + "-" + new Random().nextInt(10000) + fileName;
    }

    /**
     * 创建储存空间名称
     *
     * @param bucketName 创建存储空间名称
     * @return
     */
    public static boolean create(String bucketName) {
        CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);

        Bucket bucket = client.createBucket(createBucketRequest);
        return Objects.nonNull(bucket);
    }

    /**
     * 实现文件上传
     *
     * @param bucket 存储空间名称
     * @param obj    存储对象名称，带文件后缀
     * @param data   文件内容
     * @return
     */
    public static boolean upload(String bucket, String obj, byte[] data) {
        PutObjectRequest request = new PutObjectRequest(bucket, obj, new ByteArrayInputStream(data));
        request.setProcess("true");
        PutObjectResult result = client.putObject(request);
        return result.getResponse().getStatusCode() == 200;
    }

    /**
     * 创建访问链接
     *
     * @param bucket 存储空间名称
     * @param obj    存储对象名称，带文件名后缀
     * @param etime  访问地址的失效时间
     * @return 访问地址
     */
    public static String createUrl(String bucket, String obj, Date etime) {
        return client.generatePresignedUrl(bucket, obj, etime).toString();
    }

    public static String createAuthUrl(AssumeRoleResponse assumeRoleResponse, String obj, Date etime) {
        return getAuthorizationUrl(assumeRoleResponse, obj,etime);
    }

    /**
     * 删除文件
     *
     * @param bucket 存储空间名称
     * @param obj    存储对象名称，带文件后缀
     */
    public static void deFile(String bucket, String obj) {
        client.deleteObject(bucket, obj);
    }

    public static AssumeRoleResponse buildAliyunSTSCredentials() throws ClientException, com.aliyuncs.exceptions.ClientException {
        final AssumeRoleRequest request = new AssumeRoleRequest();
        request.setMethod(MethodType.POST);
        request.setProtocol(ProtocolType.HTTPS);
        //设置临时访问凭证的有效时间为3600秒
        request.setDurationSeconds(60 * 60 * 1L);
        // 要扮演的角色ID-刚才你创建的角色详情里面ARN
        request.setRoleArn(AliOssConfig.ALIYUN_ROLEARN);
        // 要扮演的角色名称-刚才你创建的角色详情里面角色名称
        request.setRoleSessionName(AliOssConfig.ALIYUN_ROLENAME);
        // request.setPolicy(policy);

        // 生成临时授权凭证
        final AssumeRoleResponse response = acsClient.getAcsResponse(request);
        // 临时凭据AccessKeyId
        String appKey = response.getCredentials().getAccessKeyId();
        // 临时凭据AccessKeySecret
        String appSecret = response.getCredentials().getAccessKeySecret();
        // 临时凭据SecurityToken
        String securityToken = response.getCredentials().getSecurityToken();
        String expiration = response.getCredentials().getExpiration();
        return response;
    }

    public static String getAuthorizationUrl(AssumeRoleResponse assumeRoleResponse, String fileName, Date etime) {
        if (assumeRoleResponse == null) {
            return null;
        }
        // 从STS服务获取的临时访问密钥（AccessKey ID和AccessKey Secret）。
        String accessKeyId = assumeRoleResponse.getCredentials().getAccessKeyId();
        String accessKeySecret = assumeRoleResponse.getCredentials().getAccessKeySecret();
        // 从STS服务获取的安全令牌（SecurityToken）。
        String securityToken = assumeRoleResponse.getCredentials().getSecurityToken();

        OSS ossClient = new OSSClientBuilder().build(AliOssConfig.ALIYUN_ENDPOINT, accessKeyId, accessKeySecret, securityToken);
        // 生成以GET方法访问的签名URL，访客可以直接通过浏览器访问相关内容。
        URL url = ossClient.generatePresignedUrl(AliOssConfig.ALIYUN_BUCKET, fileName, etime);
        System.out.println(url);
        return url.toString();

    }

    public static boolean uploadTemCertificate(AssumeRoleResponse assumeRoleResponse, String bucket, String obj, byte[] data) {
        if (assumeRoleResponse == null) {
            return false;
        }
        // 从STS服务获取的临时访问密钥（AccessKey ID和AccessKey Secret）。
        String accessKeyId = assumeRoleResponse.getCredentials().getAccessKeyId();
        String accessKeySecret = assumeRoleResponse.getCredentials().getAccessKeySecret();
        // 从STS服务获取的安全令牌（SecurityToken）。
        String securityToken = assumeRoleResponse.getCredentials().getSecurityToken();

        OSS ossClient = new OSSClientBuilder().build(AliOssConfig.ALIYUN_ENDPOINT, accessKeyId, accessKeySecret, securityToken);
        PutObjectRequest putObjectRequest = new PutObjectRequest(bucket, obj, new ByteArrayInputStream(data));
        ObjectMetadata metadata = new ObjectMetadata();
        // 上传文件时设置存储类型。
        metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());
        // 上传文件时设置读写权限ACL。
        metadata.setObjectAcl(CannedAccessControlList.Private);
        putObjectRequest.setMetadata(metadata);
        ossClient.putObject(putObjectRequest);

        return true;
    }
}